refactor(ui): migrate Mantine UI v8 → @ossrandom/design-system v0.3.0#71
Merged
Conversation
Replace the Mantine dependency with the RandomCodeSpace design system per
project board direction. Per-component scope is small — the UI's only
direct Mantine surface is main.tsx (provider) plus two MCP components
(Modal/Tabs).
Changes:
- main.tsx — MantineProvider to ThemeProvider; ToastRegion mounted at root
- ToolCallModal.tsx — Mantine Modal to DS Modal. DS Modal API is stricter
(no padding=0, no classNames, no styles, no custom width) so the
hand-rolled header is collapsed into title/description props and the
modal sizes to lg instead of min(880px, 100vw-2rem).
- RPCPopup.tsx — Mantine Modal+Tabs to DS Modal+Tabs. Tabs API is items
rather than children, so the methods array maps to items={[{key,label}]}.
- @mantine/core and @mantine/hooks removed from package.json
- @ossrandom/design-system@0.3.0 added (public npm; no GHP/PAT setup)
- internal/ui/dist regenerated. Net bundle is -598 / +123 lines because
Mantine CSS is gone; DS ships variable woff2 fonts (Bricolage Grotesque,
Plus Jakarta Sans, Geist Mono) as separate ~30-130KB assets that load
on demand.
- CLAUDE.md project rules updated: NO Tailwind CSS, NO Mantine — use
@ossrandom/design-system exclusively for UI components and tokens.
Raw CSS only for layout escape hatches.
Out of scope (deliberate, follow-up PRs):
- Strip ui/src/styles/tokens.css and slim global.css to layout-only.
- Migrate ServiceMap.tsx / EChart.tsx from echarts to DS charts subpath.
- Replace inline style={{display:flex…}} with DS Space/Grid/Card.
Drive-by: pin react-window to ^1.8.10 (was ^2.2.7). The v2 API is
incompatible with current LogsPage.tsx / TracesPage.tsx imports
(VariableSizeList, FixedSizeList, ListChildComponentProps no longer
exported), and the build was broken on main even before this PR. The
v2 migration is its own concern; pinning back to v1 here keeps this PR
strictly about the DS swap and gets the build green.
Verification:
- npm run build: clean
- npm run test: 32/32 pass
- Live: HTTP_PORT=37778 ./otelcontext, GET / returns the DS-styled bundle
(fonts load on demand, /assets/index-*.js + /assets/index-*.css served).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
…al shift Rewrite ui/src/styles/tokens.css so the legacy --bg-base / --text-primary / --color-accent etc. names resolve to @ossrandom/design-system tokens (--bg-0..3, --fg-1..4, --accent-fg, --border-1..3). Existing inline `var(--*)` usage and the .card/.top-nav/.nav-link rules in global.css now pick up the DS palette and fonts (Bricolage Grotesque, Plus Jakarta Sans, Geist Mono, Cod Gray on Signal Red) without touching every component. This is the thin transition shim called out as "out of scope" in the parent commit's message — a follow-up PR will replace the class-based styles in global.css with DS components and delete this file entirely. Bundle delta: -21 CSS lines (light-theme block removed; DS owns theming via ThemeProvider mode now). Live verified at oteliq.randomcodespace.dev: the new CSS hash (index-BLTTK0qH.css) ships --bg-base:var(--bg-0) plus the DS variable woff2 references for all three font families. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s + custom CSS - ServiceMap: replace echarts force-directed graph with DS ServiceMap (cose-bilkent) - TracesPage / LogsPage / ServiceSidePanel: replace .card / .badge / .side-panel classes with DS Card / Badge / Button / Alert / Input / Spin / Space - TopNav / MCP console + modals: already on DS, polished tones (mono palette) - ErrorBoundary: keep inline styles (must render if DS fails to load) but bind to DS CSS vars with hex fallbacks for theme harmony - Strip global.css to layout-only escape hatches (#root, scrollbar, code, html height); strip tokens.css to box-sizing reset + colorJSON syntax palette - Remove echarts dependency (-4 packages); delete unused EChart wrapper + tierLayout (orphaned after migration) - Net 1376 insertions / 1722 deletions; CSS bundle 49 KB (gzip 9.4 KB)
…er/Stat/Grid/CodeBlock) - App: AppShell hosts header + main content; no inline styles - TopNav: PageHeader + controlled Tabs + Stat strip; StatPill helper deleted - ServiceSidePanel: KPI grid → DS Stat (4-up); upstream/downstream lists → Card-bordered Buttons; health bar → DS Progress - TracesPage / LogsPage: 12-col Grid + Card + ScrollDiv + Space; row buttons built from DS Button + Space; pre-with-HTML eliminated - ServiceMap: side-panel split moved to Grid (8/4); toolbar → Card extra slot - MCP modals: pre+colorJSON HTML → DS CodeBlock (language="json", copyable) - ToolCard / MCPConsole / ToolCallModal / RPCPopup: Grid + Space replace inline grid/flex; Card title/extra/footer slots replace bespoke headers - Drop tokens.css entirely (--syntax-* palette unused after CodeBlock swap); global.css trimmed to browser reset only (3 rules: box-sizing, body margin, #root height) - utils.ts: drop unused colorJSON + esc helpers Net: 619 insertions / 1078 deletions; CSS bundle 48.5 KB (gzip 9.2 KB).
…treams, MCP simplified Each view now owns its own layout with PageHeader + Stat strip + a single full-width data surface, instead of cramming a split-grid into a shared container. - ServicesView: full-bleed DSServiceMap (height 620); right Drawer hosts the service detail panel on node-click. 4-up Stat strip surfaces real-time active services / error rate / total traces / total logs. - TracesView: DS Table (compact, sticky header, striped) replaces the virtualized card list; row click opens a right Drawer with the span waterfall. Stats: in-view trace count, error count, avg duration, p95 (computed locally). - LogsView: DS Table for the stream; severity Buttons + Input live in Card.extra. "Find similar" opens a right Drawer instead of stealing a side column. Stats: in-view / errors / warnings / info counts. - MCPConsole rewritten: tool cards / Call / JSON-RPC modals removed entirely. Single Card now shows the endpoint URL with copy button + three example CodeBlocks (tools/list, tools/call, curl). useMCP hook deleted. - TopNav: compact horizontal bar — brand, controlled Tabs, live/offline badge, theme toggle. Stat strip moved into per-view PageHeaders. - App: AppShell.header = TopNav; main = view switch. No serviceFilter/dashboard global chrome — each view consumes what it needs. Files removed: ToolCard.tsx, ToolCallModal.tsx, RPCPopup.tsx, useMCP.ts, ServiceMap.tsx, TracesPage.tsx, LogsPage.tsx (all replaced). Deps removed: react-window, @types/react-window (-3 packages); virtualization is unnecessary at the 200-row cap. Net 804 insertions / 1096 deletions; JS 247 KB / gzip 77 KB; CSS 48.5 KB / gzip 9.2 KB.
Mobile (≤760px) nav was unreachable — header overflowed off-screen with no hamburger. Layout was also too heavy — every Stat was its own bordered Card. - TopNav: useMediaQuery splits into compact (hamburger → left Drawer with DS Menu vertical) and wide (Tabs inline) variants - StatRow component: single Card with inline Stats separated by Divider — replaces the 4-card 12-col Grid wrapper across all three views - MCP page reduced to one Card: URL with Copy button + one paragraph on HTTP-Streamable / JSON-RPC / Bearer auth. The 3 example CodeBlocks are gone (they read as "tools" still being there). - Drawer width: number on desktop, "92vw" on mobile so it doesn't overflow - ServiceMap height: 660 desktop, 460 mobile (the map is the hero) - PageHeaders use size="sm" with inlineSubtitle to reclaim vertical space - ServicesView accepts string-or-number DBSizeMB from /api/stats (server returns "1990.0" as string while old type expected number) 11 files changed, 269 insertions / 258 deletions.
ServicesView and ServiceSidePanel: toFixed(2) instead of toFixed(1).
DS Stat renders delta.value verbatim, so passing a raw float showed e.g. "↑15.661224321%". The error-rate / error-count / warn-count deltas were also redundant with the main value (no period-over-period data). - ServicesView / ServiceSidePanel: drop delta on error-rate Stat (showed the same number as the value). - LogsView: drop delta on errors / warnings (same — count == count). - TracesView: keep p95 delta (it's a real comparison vs avg) but round to 1 decimal at the source so DS doesn't print 10 decimals.
…unters dashboard.total_traces / total_logs are *recent-window* counters, while DBSizeMB reflects the entire on-disk dataset. The mismatch made 4 GB look unjustified next to a small "Logs" number. Switch the Traces/Logs Stats to /api/stats (TraceCount/LogCount) so they reconcile with DB size; fall back to dashboard counters when /api/stats hasn't loaded yet.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Per board direction, replace Mantine with the RandomCodeSpace design system. The UI's only direct Mantine surface was 3 files (provider + 2 MCP components), so this is a focused refactor — not a full visual rewrite. Custom CSS strip and
<Card>adoption are intentionally deferred to follow-up PRs to keep this one reviewable.Drive-by build fix
Build was already broken on
main: react-window was bumped to v2 by Dependabot, butLogsPage.tsx/TracesPage.tsxstill importVariableSizeList/FixedSizeList/ListChildComponentPropswhich v2 no longer exports. Pinned back to^1.8.10here to unblock the build; the v2 API migration is its own follow-up.Files
ui/src/main.tsx—MantineProvider→ThemeProvider;ToastRegionmounted at root.ui/src/components/mcp/ToolCallModal.tsx— MantineModal→ DSModal. The DS Modal API is stricter (nopadding=0,classNames,styles, custom width) so the hand-rolled header is collapsed intotitle/descriptionprops; size maps to"lg".ui/src/components/mcp/RPCPopup.tsx— MantineModal+Tabs→ DSModal+Tabs. DSTabsusesitems={[{key, label}]}instead of children-style sub-components; the methods array translates directly.ui/package.json— drop@mantine/core+@mantine/hooks; add@ossrandom/design-system@0.3.0; pinreact-windowto^1.8.10(drive-by build fix).internal/ui/dist/*— regenerated. Bundle delta: -598 / +123 lines (Mantine CSS gone). DS variable woff2 fonts (Bricolage Grotesque, Plus Jakarta Sans, Geist Mono) ship as separate on-demand assets (~30–130 KB each).CLAUDE.md— project rule updated: "NO Tailwind CSS, NO Mantine — use@ossrandom/design-systemexclusively for UI components and tokens. Raw CSS only for layout escape hatches."Out of scope (deliberate, follow-up PRs)
ui/src/styles/tokens.css(DS provides design tokens) and slimglobal.cssto layout-only.<div className=\"card\">with DS<Card>; replace inlinestyle={{display:'flex'...}}with DS<Space>/<Grid>/<AppShell>/<PageHeader>.ServiceMap.tsx/EChart.tsxfrom echarts to the DS/chartssubpath.VariableSizeList→List).Test plan
cd ui && npm run build— cleancd ui && npm run test -- --run— 32/32 passGET /returns the DS-styled bundle/assets/*.woff2🤖 Generated with Claude Code